#include <stdio.h>

#include "prime.h"
#include "calculations.h"
#include "crypt.h"

//// Основная часть кода. Отсюда вызываются все функции

void task_1(long long int Ca, long long int Cb, long long int m, long long int p);
void task_2(long long int p, long long int m);
void task_3(long long int p, long long int x1);

void print(long long int m, long long int x4);


int main() {
    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    long long int Ca1, Cb1, p1, m1; // Значения для 1 задания.
    p1 = 3608376568252073;
    Ca1 = 2349520366664581;
    Cb1 = 2616504075945553;
    m1 = 170208516;

    /*---------------------------------------------------------------------------------*/
    long long int p2, m2; // Значения для 2 параметра.
    p2 = 3107421852068159;
    m2 = 12312312;

    /*---------------------------------------------------------------------------------*/
    long long int p3, x1_3; // Значения для 3 параметра.
    p3 = 128919139650245773;
    x1_3 = 108950223798789325;

    /*---------------------------------------------------------------------------------*/

    task_1(Ca1, Cb1, m1, p1);

    task_2(p2, m2);

    task_3(p3, x1_3);

    return 0;
}

void task_1(long long int Ca,
            long long int Cb,
            long long int m,
            long long int p) {

    // Задание 1.
    // Передаются в функцию ключи Алисы и Боба - Ca и Cb.
    // Не зашифрованное сообщение - m.
    // Параметр шифра - p.
    //
    // Рассчитываются ключи - Da и Db.
    // Производится в 4 шага шифровка-дешифровка сообщение и результат(x4) выводится на экран.

    printf("\033[92mTask_1 - \033[39m\n");

    long long int Da, Db, x4;

    Da = invert_mod(p, Ca);

    Db = invert_mod(p, Cb);

    x4 = test(Ca, Da, Cb, Db, p, m);

    print(m, x4);
}

void task_2(long long int p,
            long long int m){

    // Задание 2.
    // Передается в функцию параметр шифра - p.
    // Не зашифрованное сообщение - m.
    //
    // По параметр p производится расчет ключей - Ca, Da, Cb, Db.
    //
    // Производится в 4 шага шифровка-дешифровка сообщение и результат(x4) выводится на экран.

    printf("\033[92mTask_2 - \033[39m\n");

    long long int Ca, Da, Cb, Db, x4;

    Ca = coprime(p);
    Da = invert_mod(p, Ca);

    Cb = coprime(p);
    Db = invert_mod(p, Cb);

    x4 = test(Ca, Da, Cb, Db, p, m);

    print(m, x4);
}

void task_3(long long int p,
            long long int x1){

    // Задание 3.
    // Передается в функцию параметр шифра - p.
    // Сообщение, зашифрованное Алисой - x1.
    //
    // Пользователь выступает в роле Боба.
    //
    // По параметру p вычисляются ключи Боба(мы) - Cb и Db.
    // Рассчитывается x2 и передается Алисе.
    // Алиса рассчитывает x3 и передает Бобу(нам).
    // Боб(мы) рассчитываем x4, которое будет равно исходному неизвестному сообщению - m.
    // Выводится на экран вся переписка.

    printf("\033[92mTask_3 - \033[39m\n");

    long long int Cb = coprime(p);
    long long int Db = invert_mod(p, Cb);

    test2(x1, p, Cb, Db);
}

void print(long long int m,
           long long int x4){
    // Принимает 2 значения:
    //      m - исходное сообщение.
    //      x4 - сообщение, прошедшее 3 ступени для дешифровки(которое получает Боб в итоге).
    // Выводит на экран значения этих переменных и сравнивает их "равенство":
    //      1 - значения равны(true).
    //      0 - значения не равны(false).
    printf("\t\033[36m Исходное сообщение -\033[39m %llu, \033[36m раскодированное сообщение -\033[39m %llu, \033[36m равенство -\033[39m %d\n", m, x4, m == x4);

}


